package rad.framework.seam;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import rad.framework.jsf.JsfUtil;

import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.core.Conversation;
import org.jboss.seam.core.ResourceBundle;

@Name("recentHistory")
@Scope(ScopeType.SESSION)
@BypassInterceptors
public class RecentHistory implements Serializable {
	private static final long serialVersionUID = 1L;

	private Set<HistoryItem> history = new HashSet<HistoryItem>();

	private List<HistoryItem> sortedHistory = new ArrayList<HistoryItem>();

	public List<HistoryItem> getHistory() {
		return sortedHistory;
	}

	public void clear() {
		history.clear();
	}

	public void addRecentItem(String editor, String entityName, String text, Object id) {
		HistoryItem item = new HistoryItem(editor, entityName, text, id);
		history.remove(item);
		history.add(item);
		sort();
	}

	public void removeRecentItem(String editor, Object id) {
		HistoryItem item = new HistoryItem(editor, id);
		history.remove(item);
		sort();
	}

	protected void sort() {
		sortedHistory = new ArrayList<HistoryItem>(history);
		Collections.sort(sortedHistory, new Comparator<HistoryItem>() {
			public int compare(HistoryItem lh, HistoryItem rh) {
				int comp = lh.getLabel().compareTo(rh.getLabel());
				return (comp != 0 ? comp : lh.getText().compareTo(
						rh.getText()));
			}
		});
	}

	public static RecentHistory instance() {
		return (RecentHistory) Component.getInstance(RecentHistory.class);
	}
	
	public class HistoryItem {
		private String editor;
		private String entityName;
		private String label;
		private String text;
		private Object id;
		private String viewId;
		private String conversationId;

		public HistoryItem(String editor, Object id) {
			this.editor = editor;
			this.id = id;
		}

		public HistoryItem(String editor, String entityName, String text, Object id) {
			this.editor = editor;
			this.entityName = entityName;
			this.label = ResourceBundle.instance().getString(entityName);
			this.text = text;
			this.id = id;
			this.viewId = JsfUtil.getViewId().replace("Edit", "View");
			this.conversationId = Conversation.instance().getId();
		}

		public String getEntityName() {
			return entityName;
		}

		public void setEntityName(String entityName) {
			this.entityName = entityName;
		}

		public String getLabel() {
			return label;
		}

		public void setLabel(String label) {
			this.label = label;
		}

		public String getText() {
			return text;
		}

		public void setText(String text) {
			this.text = text;
		}

		public Object getId() {
			return id;
		}

		public void setId(Object id) {
			this.id = id;
		}

		public String getViewId() {
			return viewId;
		}

		public void setViewId(String viewId) {
			this.viewId = viewId;
		}

		public String getConversationId() {
			return conversationId;
		}

		public void setConversationId(String conversationId) {
			this.conversationId = conversationId;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result
					+ ((editor == null) ? 0 : editor.hashCode());
			result = prime * result + ((id == null) ? 0 : id.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			final HistoryItem other = (HistoryItem) obj;
			if (editor == null) {
				if (other.editor != null)
					return false;
			} else if (!editor.equals(other.editor))
				return false;
			if (id == null) {
				if (other.id != null)
					return false;
			} else if (!id.equals(other.id))
				return false;
			return true;
		}
	}
}
